package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"
)

//获取指定目录及所有子目录下的所有文件。
func WalkDir(dirPth string, fn func(string, os.FileInfo) error) (err error) {
	err = filepath.Walk(dirPth, func(filename string, fi os.FileInfo, err error) error { //遍历目录
		//if err != nil { //忽略错误
		// return err
		//}

		if fi.IsDir() { // 忽略目录
			return nil
		}

		fn(filename, fi)

		return nil
	})

	return
}

func CheckErr(err error) {
	if err != nil {
		log.Println(err.Error())
		os.Exit(-1)
	}
}
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	/*
		c := exec.Command("taskkill.exe", "/f", "/im", "delCache.exe")
		err := c.Start()
		CheckErr(err)
	*/
	f, err := os.Open("conf.ini")
	CheckErr(err)
	defer f.Close()
	b, err := ioutil.ReadAll(f)
	CheckErr(err)
	//log.Println(string(b))
	var dirs []string = make([]string, 0)
	var hour int = 2            //几点开始执行
	var old float64 = 2 * 86400 //删掉几天以前的
	lines := strings.Split(string(b), "\n")
	if len(lines) > 0 {
		for _, line := range lines {
			line = strings.TrimSpace(line)
			if line[0] == '#' || line == "" {
				continue
			}
			kv := strings.Split(line, "=")
			if len(kv) > 1 {
				switch strings.TrimSpace(kv[0]) {
				case "dir":
					dStr := strings.TrimSpace(kv[1])
					dStr = strings.Replace(dStr, `\`, "/", -1)
					dirs2 := strings.Split(dStr, ";")
					if len(dirs2) > 0 {
						for _, dir := range dirs2 {
							if strings.Contains(dir, "/temp/") {
								dir, _ = filepath.Abs(strings.TrimSpace(dir))
								log.Println("watch dir:", dir)
								dirs = append(dirs, dir)
							}
						}
					}
				case "hour":
					hour, _ = strconv.Atoi(strings.TrimSpace(kv[1]))
				case "old":
					oStr := strings.TrimSpace(kv[1])
					oLen := len(oStr)
					switch oStr[oLen-1:] {
					case "h":
						old, _ = strconv.ParseFloat(oStr[0:oLen-1], 64)
						old = old * 3600
					case "m":
						old, _ = strconv.ParseFloat(oStr[0:oLen-1], 64)
						old = old * 60
					case "s":
						old, _ = strconv.ParseFloat(oStr[0:oLen-1], 64)
					case "d":
						old, _ = strconv.ParseFloat(oStr[0:oLen-1], 64)
						old = old * 86400
					default:
						old, _ = strconv.ParseFloat(oStr, 64)
						old = old * 86400
					}
				}
			}
		}
	}
	var lastRunDay int = 0
	if len(dirs) > 0 && hour > 0 {
		for {
			today := time.Now().Day()
			if today != lastRunDay && time.Now().Hour() > hour {
				s := new(sync.WaitGroup)
				s.Add(len(dirs))
				log.Println("开始清理:")
				for k, dir := range dirs {
					go func(k int, dir string) {
						WalkDir(dir, func(filename string, fi os.FileInfo) error {
							if time.Now().Sub(fi.ModTime()).Seconds() > old && strings.Contains(filename, "#") == false {
								log.Println("["+fmt.Sprintf("%v", k)+"][Mod:"+fi.ModTime().String()+"][deleted]", filename)
								os.Remove(filename)
							} else {
								log.Println("["+fmt.Sprintf("%v", k)+"][Mod:"+fi.ModTime().String()+"][skiped]", filename)
							}
							return nil
						})
						s.Done()
					}(k, dir)
				}
				s.Wait()
				lastRunDay = today
				log.Println("今日清理任务完成。")
			} else {
				fmt.Println("时间未到。")
			}
			time.Sleep(5 * time.Second)
		}
	}
}
